package solutions;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.pi4.locutil.io.TraceGenerator;
import org.pi4.locutil.trace.Parser;
import org.pi4.locutil.trace.TraceEntry;

import solutions.MainAlgorithmRunner.TraceEstimater;

public class RadioMapPrinter {

	static final int offlineSize = 25;
	static final int onlineSize = 5;
	static final String wifiPositionsPath = "data/MU.AP.positions";
	
	public static void main(String[] args) throws NumberFormatException, IOException {
		Parser offlineParser = new Parser(new File(
				"data/MU.1.5meters.offline.trace"));
		Parser onlineParser = new Parser(new File(
				"data/MU.1.5meters.online.trace"));
		List<Double> differences = new ArrayList<Double>(offlineSize);
		List<TraceEntry> apPositions = WifiPositionsParser
				.parser(wifiPositionsPath);
		
		TraceGenerator tg = new TraceGenerator(offlineParser, onlineParser,
				offlineSize, onlineSize);
		tg.generate();
		
		TraceEstimater estimater = new ModelNN(tg, differences, apPositions);
		//TraceEstimater estimater = new FingerPrintingKNN(tg, differences, 3);
		List<TraceEntry> onlineTrace = tg.getOnline();
		estimater.buildRadioMap(onlineTrace);
		//estimater.buildRadioMap(tg.getOffline());
		//List of EntryWithMacs.. (GeoPosition = Grid position, Map<MACAddress, dBm from geoposition to AP>)
		List<EntryWithMACsAndAverages> radioMap = estimater.getRadioMap();
		Map<Integer, List<Double>> distanceTodBm = new HashMap<Integer, List<Double>>();
		
		double dBm = 0.0f;
		for(EntryWithMACsAndAverages e : radioMap) {
			for(TraceEntry ap : apPositions) {
				int d = (int)PositionUtils.getDistance(e.getPosition(), ap.getGeoPosition());
				if(distanceTodBm.get(d) == null) {
					distanceTodBm.put(d, new ArrayList<Double>());
				}
				if(e.getAddressMap().get(ap.getId()) != null) {
					dBm = e.getAddressMap().get(ap.getId());
					distanceTodBm.get(d).add(dBm);
				}
			}
		}
		
		BufferedWriter writer = new BufferedWriter(new FileWriter(new File("radioMap.txt")));
		Set<Integer> kSet = distanceTodBm.keySet();
		List<Integer> kList = new ArrayList<Integer>(kSet);
		Collections.sort(kList);
		for(Integer i : kList) {
			double avg = getAvg(distanceTodBm.get(i));
			if(!Double.isNaN(avg)) {
				writer.write(i+"\t"+avg+"\n");
			}
		}
		writer.flush();
		writer.close();
	}
	
	private static Map<Integer, List<Double>> calculateDistanceMap() {
		return null;
	}
	
	private static double getAvg(List<Double> dBmList) {
		double sum = 0.0f;
		for(Double d : dBmList) {
			sum += d;
		}
		return sum/dBmList.size();
	}
}
